package com.tools.web.work.excel.poi;

import com.tools.common.object.Note;
import org.apache.poi.ss.usermodel.CellStyle;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 导出 Excel 时 Sheet 页的构建对象
 * */
@Note("导出 Excel 时 Sheet 页的构建对象")
public class SheetExportBuilder {

    @Note("sheet 页的名称")
    private String sheetName;

    @Note("表头行的高度")
    private int headHeight = 40;

    @Note("除了表头行外，每一行的高度")
    private int rowHeight = 25;

    @Note("表头的样式")
    private CellStyle headStyle;

    @Note("表单元格的样式")
    private CellStyle cellStyle;

    @Note("表头配置类")
    private ExcelHead excelHead;

    @Note("是否合并所有相邻的相同值的单元格")
    private boolean sameMergeOfAllField;

    @Note("合并单元格索引记录容器")
    private Map<Object, List<MergeCell>> mergeCellIndexMap;

    /* ************************************************************************************************************
     *
     *      构造器
     *
     * ************************************************************************************************************
     * */

    public SheetExportBuilder(ExcelHead excelHead) {
        this.setExcelHead(excelHead);
    }

    public static SheetExportBuilder of(ExcelHead excelHead) {
        return new SheetExportBuilder(excelHead);
    }

    /* ************************************************************************************************************
     *
     *      Getter / Setter
     *
     * ************************************************************************************************************
     * */

    public String getSheetName() {
        return sheetName;
    }

    public void setSheetName(String sheetName) {
        this.sheetName = sheetName;
    }

    public int getHeadHeight() {
        return headHeight;
    }

    public void setHeadHeight(int headHeight) {
        this.headHeight = (headHeight > 0) ? headHeight : 40;
    }

    public int getRowHeight() {
        return rowHeight;
    }

    public void setRowHeight(int rowHeight) {
        this.rowHeight = (rowHeight > 0) ? rowHeight : 25;
    }

    public CellStyle getHeadStyle() {
        return headStyle;
    }

    public void setHeadStyle(CellStyle headStyle) {
        this.headStyle = headStyle;
    }

    public CellStyle getCellStyle() {
        return cellStyle;
    }

    public void setCellStyle(CellStyle cellStyle) {
        this.cellStyle = cellStyle;
    }

    public ExcelHead getExcelHead() {
        return excelHead;
    }

    public void setExcelHead(ExcelHead excelHead) {
        if(excelHead == null) throw new NullPointerException("Excel 表头配置为 null");
        this.excelHead = excelHead;
    }

    public Map<Object, List<MergeCell>> getMergeCellIndexMap() {
        return mergeCellIndexMap;
    }

    public void setMergeCellIndexMap(Map<Object, List<MergeCell>> mergeCellIndexMap) {
        this.mergeCellIndexMap = mergeCellIndexMap;
    }

    public boolean isSameMergeOfAllField() {
        return sameMergeOfAllField;
    }

    public void setSameMergeOfAllField(boolean sameMergeOfAllField) {
        this.sameMergeOfAllField = sameMergeOfAllField;
    }

    @Override
    public String toString() {
        return "SheetBuilder{" +
                "sheetName='" + sheetName + '\'' +
                ", headHeight=" + headHeight +
                ", rowHeight=" + rowHeight +
                ", headStyle=" + headStyle +
                ", cellStyle=" + cellStyle +
                ", excelHead=" + excelHead +
                ", sameMergeOfAllField=" + sameMergeOfAllField +
                ", mergeCellIndexMap=" + mergeCellIndexMap +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SheetExportBuilder builder = (SheetExportBuilder) o;
        return Objects.equals(sheetName, builder.sheetName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(sheetName);
    }

    /* ************************************************************************************************************
     *
     *      链式调用
     *
     * ************************************************************************************************************
     * */

    public SheetExportBuilder sheetName(String sheetName) {
        this.setSheetName(sheetName);
        return this;
    }

    public SheetExportBuilder headHeight(int headHeight) {
        this.setHeadHeight(headHeight);
        return this;
    }

    public SheetExportBuilder rowHeight(int rowHeight) {
        this.setRowHeight(rowHeight);
        return this;
    }

    public SheetExportBuilder headStyle(CellStyle headStyle) {
        this.setHeadStyle(headStyle);
        return this;
    }

    public SheetExportBuilder cellStyle(CellStyle cellStyle) {
        this.setCellStyle(cellStyle);
        return this;
    }

    public SheetExportBuilder excelHead(ExcelHead excelHead) {
        this.setExcelHead(excelHead);
        return this;
    }

    public SheetExportBuilder mergeCellIndexMap(Map<Object, List<MergeCell>> mergeCellIndexMap) {
        this.setMergeCellIndexMap(mergeCellIndexMap);
        return this;
    }

    public SheetExportBuilder sameMergeOfAllField(boolean sameMergeOfAllField) {
        this.setSameMergeOfAllField(sameMergeOfAllField);
        return this;
    }
}
